package Thread;
//实现阻塞队列
//并实现生产消费者模型
public class ThreadDemo18 {
    public static class BlockingQueue{
        int[] elem=new int[100];
        int size=0;
        int tail=0;
        int head=0;
        public  void put(int val) throws InterruptedException {
            synchronized (this){
                while(size==elem.length){//最好写作while
                    //队列满需阻塞
                    this.wait();
                }
                elem[tail]=val;
                tail++;
                if(tail>=elem.length){
                    tail=0;
                }
                size++;
                //唤醒take
                this.notify();
            }
        }
        public int take() throws InterruptedException {
            synchronized (this){
                if(size==0){
                    //队列为空需阻塞
                    this.wait();
                }
                int val=elem[head];
                head++;
                while (head>=elem.length){//wait被唤醒后再次确认条件是否成立
                    head=0;
                }
                size--;
                //唤醒put的wait
                this.notify();
                return val;
            }
        }
    }

    public static void main(String[] args) {
        BlockingQueue queue=new BlockingQueue();
        Thread producer=new Thread(){
            @Override
            public void run() {
                for (int i = 0; i <1000 ; i++) {
                    System.out.println("生产一个元素："+i);
                    try {
                        queue.put(i);
                        //Thread.sleep(1000);

                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        };
        producer.start();
        Thread customer=new Thread(){
            @Override
            public void run() {
                while (true){
                    try {
                        int tmp=queue.take();
                        System.out.println("消费一个元素："+tmp);
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        };
        customer.start();
        try {
            producer.join();
            customer.start();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
